package com.atguigu.gmall.item.service;

import com.alibaba.csp.sentinel.util.StringUtil;
import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.item.feign.GmallPmsClient;
import com.atguigu.gmall.item.feign.GmallSmsClient;
import com.atguigu.gmall.item.feign.GmallWmsClient;
import com.atguigu.gmall.item.vo.ItemVo;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.pms.vo.ItemGroupVo;
import com.atguigu.gmall.pms.vo.SaleAttrValueVo;
import com.atguigu.gmall.sms.vo.ItemSaleVo;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

@Service
public class ItemService {
    @Autowired
    private GmallPmsClient pmsClient;
    @Autowired
    private GmallSmsClient smsClient;
    @Autowired
    private GmallWmsClient wmsClient;
    @Autowired
    private ExecutorService executorService;
    @Autowired
    private TemplateEngine templateEngine;
    public ItemVo loadData(Long skuId) {
        ItemVo itemVo = new ItemVo();
        //1.根据skuId查询sku
        CompletableFuture<SkuEntity> skuFuture = CompletableFuture.supplyAsync(() -> {
            ResponseVo<SkuEntity> skuEntityResponseVo = pmsClient.querySkuById(skuId);
            SkuEntity skuEntity = skuEntityResponseVo.getData();
            if (skuEntity == null) {
                throw new RuntimeException("访问的页面不存在");
            }
            itemVo.setSkuId(skuId);
            itemVo.setTitle(skuEntity.getTitle());
            itemVo.setSubtitle(skuEntity.getSubtitle());
            itemVo.setPrice(skuEntity.getPrice());
            itemVo.setWeight(skuEntity.getWeight());
            itemVo.setDefaultImage(skuEntity.getDefaultImage());
            return skuEntity;
        }, executorService);


        //2.根据三级分类id查询一二三级分类
        CompletableFuture<Void> levelFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<List<CategoryEntity>> queryLevel123ByCid3 = pmsClient.queryLevel123ByCid3(skuEntity.getCategoryId());
            List<CategoryEntity> categoryEntities = queryLevel123ByCid3.getData();
            itemVo.setCategories(categoryEntities);
        }, executorService);


        //3.根据品牌id查询品牌
        CompletableFuture<Void> brandFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<BrandEntity> brandEntityResponseVo = pmsClient.queryBrandById(skuEntity.getBrandId());
            BrandEntity brandEntity = brandEntityResponseVo.getData();
            if (brandEntity != null) {
                itemVo.setBrandId(brandEntity.getId());
                itemVo.setBrandName(brandEntity.getName());
            }
        }, executorService);


        //4.根据spuId查询spu
        CompletableFuture<Void> spuFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<SpuEntity> spuEntityResponseVo = pmsClient.querySpuById(skuEntity.getSpuId());
            SpuEntity spuEntity = spuEntityResponseVo.getData();
            if (spuEntity != null) {
                itemVo.setSpuId(spuEntity.getId());
                itemVo.setSpuName(spuEntity.getName());
            }
        }, executorService);


        //5.根据skuId查询sku的图片列表
        CompletableFuture<Void> imagesFuture = CompletableFuture.runAsync(() -> {
            ResponseVo<List<SkuImagesEntity>> listResponseVo = pmsClient.queryImagesBySkuId(skuId);
            List<SkuImagesEntity> skuImagesEntities = listResponseVo.getData();
            if (CollectionUtils.isNotEmpty(skuImagesEntities)) {
                itemVo.setImages(skuImagesEntities);
            }
        }, executorService);


        //6.根据skuId查询优惠信息
        CompletableFuture<Void> salesFuture = CompletableFuture.runAsync(() -> {
            ResponseVo<List<ItemSaleVo>> listResponseVo1 = smsClient.querySalesBySkuId(skuId);
            List<ItemSaleVo> itemSaleVoList = listResponseVo1.getData();
            if (CollectionUtils.isNotEmpty(itemSaleVoList)) {
                itemVo.setSales(itemSaleVoList);
            }
        }, executorService);


        //7.根据skuId查询库存信息
        CompletableFuture<Void> wareFuture = CompletableFuture.runAsync(() -> {
            ResponseVo<List<WareSkuEntity>> wmsClientBySkuId = wmsClient.getBySkuId(skuId);
            List<WareSkuEntity> wareSkuEntities = wmsClientBySkuId.getData();
            if (CollectionUtils.isNotEmpty(wareSkuEntities)) {
                itemVo.setStore(wareSkuEntities.stream().anyMatch(
                        wareSkuEntity -> wareSkuEntity.getStock() - wareSkuEntity.getStockLocked() > 0));
            }
        }, executorService);


        //8.根据spuId查询spu下所有sku的销售属性
        CompletableFuture<Void> skuSalesFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<List<SaleAttrValueVo>> listResponseVo2 = pmsClient.querySaleAttrValueBySpuId(skuEntity.getSpuId());
            List<SaleAttrValueVo> saleAttrValueVos = listResponseVo2.getData();
            if (CollectionUtils.isNotEmpty(saleAttrValueVos)) {
                itemVo.setSaleAttrs(saleAttrValueVos);
            }
        }, executorService);


        //9.根据skuId查询当前sku的销售属性
        CompletableFuture<Void> skuAttrFuture = CompletableFuture.runAsync(() -> {
            ResponseVo<List<SkuAttrValueEntity>> listResponseVo3 = pmsClient.querySkuAttrValueBySKuId(skuId);
            List<SkuAttrValueEntity> skuAttrValueEntityList = listResponseVo3.getData();
            if (CollectionUtils.isNotEmpty(skuAttrValueEntityList)) {
                itemVo.setSaleAttr(skuAttrValueEntityList.stream().collect(
                        Collectors.toMap(SkuAttrValueEntity::getAttrId, SkuAttrValueEntity::getAttrValue)));
            }
        }, executorService);


        //10.根据spuId查询出spu下所有销售属性组合与skuId的映射关系
        CompletableFuture<Void> mappingFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<String> stringResponseVo = pmsClient.queryMappingBySpuId(skuEntity.getSpuId());
            String json = stringResponseVo.getData();
            if (StringUtil.isNotBlank(json)) {
                itemVo.setSkuJsons(json);
            }
        }, executorService);


        //11.根据spuId查询spu的图片列表
        CompletableFuture<Void> skuImagesFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<SpuDescEntity> spuDescEntityResponseVo = pmsClient.querySpuDescById(skuEntity.getSpuId());
            SpuDescEntity spuDescEntity = spuDescEntityResponseVo.getData();
            if (spuDescEntity != null) {
                itemVo.setSpuImages(Arrays.asList(StringUtils.split(spuDescEntity.getDecript(), ",")));
            }
        }, executorService);


        //12.查询分组及组下的规格参数和值
        CompletableFuture<Void> groupFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<List<ItemGroupVo>> listResponseVo4 = pmsClient.queryGroupWithAndValueByCidAndSpuIdAndSkuId(skuEntity.getCategoryId(), skuEntity.getSpuId(), skuId);
            List<ItemGroupVo> itemGroupVoList = listResponseVo4.getData();
            if (CollectionUtils.isNotEmpty(itemGroupVoList)) {
                itemVo.setGroups(itemGroupVoList);
            }
        }, executorService);

        //阻塞等待所有线程全部完成
        CompletableFuture.allOf(groupFuture,skuImagesFuture,mappingFuture,skuAttrFuture,skuSalesFuture
        ,wareFuture,salesFuture,imagesFuture,spuFuture,brandFuture,levelFuture).join();

        //多线程异步化生成静态页面
        executorService.execute(()->generateHtml(itemVo));

        return itemVo;
    }
    //渲染静态页面
    private void generateHtml(ItemVo itemVo){
        //写入的文件地址
        try(PrintWriter printWriter = new PrintWriter("G:\\Down\\"+itemVo.getSkuId()+".html")) {
            Context context = new Context();
            //item模板占位符参数名为itemVo，名字必须设置一致
            context.setVariable("itemVo",itemVo);
            //获取模板item.html，将占位符或表达式替换为提供的 ItemVo 对象中的实际数据
            templateEngine.process("item",context,printWriter);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}

